use crate::{animate::Animator, class::{Class, GameCommands, UiChildBuilder}};
use bevy::prelude::*;

pub fn root<'ui, P>(
    class: impl Class<'ui, P>,
    commands: &mut GameCommands<'ui, '_, '_>,
    parent: impl FnOnce(&mut UiChildBuilder),
) {
    commands.insert_bundle(SpriteBundle::default());
    class.apply(commands.game_resource.as_unsafe());
    let bundle = commands.take_bundle::<SpriteBundle>();
    commands.spawn(bundle).with_children(parent);
}

macro_rules! widget_animate_transform {
    ($name:ident, $bundle:ident) => {
        pub fn $name<'a, P>(class: impl Class<'a, P>, commands: &mut UiChildBuilder<'a, '_, '_, '_, '_>) {
            commands.insert_bundle($bundle::default()).insert_bundle(Animator::default());
            class.apply(commands.game_resource);
            let bundle = commands.take_bundle::<$bundle>();
            let mut animator = commands.take_bundle::<Animator>();
            animator.init_start_transform(&bundle.transform);
            commands.spawn((bundle, animator));
        }
    };
}

widget_animate_transform!(sprite, SpriteBundle);
widget_animate_transform!(sprite_sheet, SpriteSheetBundle);
macro_rules! widget_animate_transform_children {
    ($name:ident, $bundle:ident) => {
        pub fn $name<'a, P>(
            class: impl Class<'a, P>,
            commands: &mut UiChildBuilder<'a, '_, '_, '_, '_>,
            parent: impl FnOnce(&mut UiChildBuilder),
        ) {
            commands.insert_bundle($bundle::default()).insert_bundle(Animator::default());
            class.apply(commands.game_resource);
            let bundle = commands.take_bundle::<$bundle>();
            let mut animator = commands.take_bundle::<Animator>();
            animator.init_start_transform(&bundle.transform);
            commands.spawn((bundle, animator)).with_children(parent);
        }
    };
}

widget_animate_transform_children!(sprite_children, SpriteBundle);
widget_animate_transform_children!(sprite_sheet_children, SpriteSheetBundle);